import { reactive, ref } from 'vue';
import webConfig from './webConfig'

interface Role {
    Name: string,
    DisplayName: string,
    Menus: any[],
    NotSetEquals: number,
    Permissions: string[]
}

interface CurrentUser {
    RealName: string,
    Avatar: string,
    Code: string,
    Roles: Role[],
    currentRole: Role,
    currentRoleIndex: number,
    switchRole: (nv : number) => void,
    succeed (permissionOrMenu : string) : Boolean,
    ver: number
}

const requestKey = webConfig.requestKey;
const alphabets = "abcdefghijklmnopqrstuvwxyz";
const defaultRole : Role = { "Name": "匿名用户", "DisplayName": "匿名用户", NotSetEquals: -1, "Permissions": [], "Menus": [] };

let accessToken = {
    requestKey, 
    token: ""
}

let currentUser: CurrentUser = reactive({ 
    "Code": "", 
    "RealName": "测试", 
    "Avatar": "", 
    "Roles": [ defaultRole ],
    currentRole: defaultRole,
    currentRoleIndex: 0,
    switchRole,
    succeed,
    ver: 0,
});
let token = "";
let isLogined = false;

function succeed (permissionOrMenu : string) : Boolean {
    let r = currentUser.currentRole;
    if (r.Permissions.indexOf(permissionOrMenu) > -1) {
        return true;
    }

    return r.NotSetEquals === 0 || !!r.Menus.find(e => { return e.path === permissionOrMenu || (e.children as any[]).find(x => x.path === permissionOrMenu) });
}

function switchRole (nv : number) {
    currentUser.currentRoleIndex = nv;
    currentUser.currentRole = currentUser.Roles.length > nv ? currentUser.Roles[nv] : defaultRole;
    accessToken.token = token +  alphabets[nv];
	uni.setStorageSync(requestKey, accessToken.token);
    currentUser.ver++;
}

async function setCurrentUser(msg: any) {
    if (!msg.success) {
        isLogined = false;
        return;
    }
    Object.assign(currentUser, msg.data);
    token = (msg.token as string);
    let index: number = alphabets.indexOf(token.charAt(token.length - 1));
    token = token.slice(0, token.length - 1);
    switchRole(index);
    isLogined = true;
	
	let dictModule = await import('@/utils/useDictionary');
	let app = await import('@/app');
	app.default.toText = dictModule.default;
}

const isMobile = ref(false);
const isWechat = ref(false);
const isWorkWechat = ref(false);
const platform = ref("");

function getQuery () {
	try{
		const url = window.location.href;
		const regex = /[?&]token(=([^&#]*)|&|#|$)/;
		const results = regex.exec(url);
		const paramValue = results[2];
		return paramValue;
	} catch (e) {
		return null;
	}
}

async function validateCurrentUser () {
    accessToken.token = getQuery() || uni.getStorageSync(requestKey) || "";
    token = accessToken.token.slice(0, token.length - 1);
	
	let promise = new Promise<any>((resolve, reject) => {
		uni.request({
			url: webConfig.domain + "/api/authorize/ValidateToken",
			header: {
				[accessToken.requestKey]: accessToken.token
			},
			success (res) {
				resolve(res.data);
			},
			fail (err) {
				reject(err);
			}
		});
	});
	let msg = await promise;
	platform.value = msg.platform;
	isMobile.value = msg.isMobile;
	isWechat.value = msg.isWechat;
	isWorkWechat.value = msg.isWorkWechat;
    if (msg.success) {
        await setCurrentUser(msg);
    } else {        
        isLogined = false;
    }

    return isLogined;
}

async function logout () {
	let promise = new Promise((resolve, reject) => {
		uni.request({
			url: webConfig.domain + "/api/authorize/logout",
			header: {
				[accessToken.requestKey]: accessToken.token
			},
			success (res) {
				resolve(res.data);
			},
			fail (err) {
				reject(err);
			}
		});
	});
    await promise;
    isLogined = false;
}

export {
    currentUser,
    accessToken,
    switchRole,
    setCurrentUser,
    validateCurrentUser,
    isLogined,
    logout,
	platform,
	isMobile,
	isWechat,
	isWorkWechat
}

export type {
    Role,
    CurrentUser,
}